<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 6.2.&nbsp; Password File</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch06lev1sec1.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch06lev1sec3.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch06lev1sec2"></a>
<h3 class="docSection1Title">6.2. Password File</h3>
<p class="docText">The UNIX System's password file, called the user database by POSIX.1, contains the fields shown in <a class="docLink" href="#ch06fig01">Figure 6.1</a>. These fields are contained in a <tt>passwd</tt> structure that is defined in <tt>&lt;pwd.h&gt;</tt>.</P>
<a name="ch06fig01"></a><P><table cellspacing="0" class="allBorders" border="1" RULES="groups" cellpadding="5"><caption><h5 class="docTableTitle">Figure 6.1. Fields in <tt>/etc/passwd</tt> file</H5></caption><colgroup><col width="175"><col width="175"><col width="30"><col width="30"><col width="30"><col width="30"><col width="30"></colgroup><thead><TR><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Description</span></P></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman"><tt>struct passwd</tt> member</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">POSIX.1</span></P></th><th class="bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">FreeBSD 5.2.1</span></P></th><th class="bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Linux 2.4.22</span></P></th><th class="bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Mac OS X 10.3</span></p></th><th class="bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Solaris 9</span></P></th></tr></thead><TR><TD class="rightBorder" align="left" valign="top"><p class="docText">user name</P></td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>char *pw_name</tt></P></td><TD class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</P></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText">encrypted password</p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>char *pw_passwd</tt></p></td><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></TD></TR><tr><TD class="rightBorder" align="left" valign="top"><p class="docText">numerical user ID</p></TD><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>uid_t pw_uid</tt></P></td><TD class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText">numerical group ID</p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>gid_t pw_gid</tt></p></td><td class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td></TR><TR><TD class="rightBorder" align="left" valign="top"><p class="docText">comment field</p></TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>char *pw_gecos</tt></P></TD><TD class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD></tr><TR><td class="rightBorder" align="left" valign="top"><p class="docText">initial working directory</p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>char *pw_dir</tt></p></td><td class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD></TR><TR><td class="rightBorder" align="left" valign="top"><p class="docText">initial shell (user program)</P></TD><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>char *pw_shell</tt></p></TD><td class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</P></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD></tr><TR><td class="rightBorder" align="left" valign="top"><p class="docText">user access class</P></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>char *pw_class</tt></p></td><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="left" valign="top">&nbsp;</td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="left" valign="top">&nbsp;</td></tr><TR><TD class="rightBorder" align="left" valign="top"><p class="docText">next time to change password</p></TD><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>time_t pw_change</tt></P></td><TD class="rightBorder" align="left" valign="top">&nbsp;</TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><td class="docTableCell" align="left" valign="top">&nbsp;</TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="left" valign="top">&nbsp;</TD></tr><TR><TD class="rightBorder" align="left" valign="top"><p class="docText">account expiration time</p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>time_t pw_expire</tt></p></TD><td class="rightBorder" align="left" valign="top">&nbsp;</TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><td class="docTableCell" align="left" valign="top">&nbsp;</td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="left" valign="top">&nbsp;</td></tr></table></p><br>
<blockquote>
<p class="docText">Note that POSIX.1 specifies only five of the ten fields in the <tt>passwd</tt> structure. Most platforms support at least seven of the fields. The BSD-derived platforms support all ten.</p>
</blockquote>
<p class="docText"><a name="idd1e42125"></a><a name="idd1e42130"></a><a name="idd1e42133"></a><a name="idd1e42136"></a><a name="idd1e42139"></a><a name="idd1e42144"></a><a name="idd1e42147"></a><a name="idd1e42152"></a>Historically, the password file has been stored in <tt>/etc/passwd</tt> and has been an ASCII file. Each line contains the fields described in <a class="docLink" href="#ch06fig01">Figure 6.1</a>, separated by colons. For example, four lines from the <tt>/etc/passwd</tt> file on Linux could be</p>

<pre>
    root:x:0:0:root:/root:/bin/bash
    squid:x:23:23::/var/spool/squid:/dev/null
    nobody:x:65534:65534:Nobody:/home:/bin/sh
    sar:x:205:105:Stephen Rago:/home/sar:/bin/bash
</pre><br>

<p class="docText">Note the following points about these entries.</p>
<ul><li><p class="docList">There is usually an entry with the user name <tt>root</tt>. This entry has a user ID of 0 (the superuser).</P></LI><li><p class="docList">The encrypted password field contains a single character as a placeholder where older versions of the UNIX System used to store the encrypted password. Because it is a security hole to store the encrypted password in a file that is readable by everyone, encrypted passwords are now kept elsewhere. We'll cover this issue in more detail in the next section when we discuss passwords.</P></LI><LI><p class="docList">Some fields in a password file entry can be empty. If the encrypted password field is empty, it usually means that the user does not have a password. (This is not recommended.) The entry for <tt>squid</tt> has one blank field: the comment field. An empty comment field has no effect.</p></LI><LI><p class="docList">The shell field contains the name of the executable program to be used as the login shell for the user. The default value for an empty shell field is usually <tt>/bin/sh</tt>. Note, however, that the entry for <tt>squid</tt> has <tt>/dev/null</tt> as the login shell. Obviously, this is a device and cannot be executed, so its use here is to prevent anyone from logging in to our system as user <tt>squid</tt>.</P><blockquote><p><p class="docList">Many services have separate user IDs for the daemon processes (<a class="docLink" href="ch13.html#ch13">Chapter 13</a>) that help implement the service. The <tt>squid</tt> enTRy is for the processes implementing the <tt>squid</tt> proxy cache service.</p></P></blockquote></LI><LI><p class="docList"><a name="idd1e42233"></a><a name="idd1e42238"></a><a name="idd1e42243"></a><a name="idd1e42248"></a><a name="idd1e42255"></a><a name="idd1e42262"></a><a name="idd1e42265"></a><a name="idd1e42268"></a><a name="idd1e42273"></a><a name="idd1e42278"></a><a name="idd1e42283"></a>There are several alternatives to using <tt>/dev/null</tt> to prevent a particular user from logging in to a system. It is common to see <tt>/bin/false</tt> used as the login shell. It simply exits with an unsuccessful (nonzero) status; the shell evaluates the exit status as false. It is also common to see <tt>/bin/true</tt> used to disable an account. All it does is exit with a successful (zero) status. Some systems provide the <tt>nologin</tt> command. It prints a customizable error message and exits with a nonzero exit status.</p></LI><LI><p class="docList">The <tt>nobody</tt> user name can be used to allow people to log in to a system, but with a user ID (65534) and group ID (65534) that provide no privileges. The only files that this user ID and group ID can access are those that are readable or writable by the world. (This assumes that there are no files specifically owned by user ID 65534 or group ID 65534, which should be the case.)</p></LI><LI><p class="docList">Some systems that provide the <tt>finger</tt>(1) command support additional information in the comment field. Each of these fields is separated by a comma: the user's name, office location, office phone number, and home phone number. Additionally, an ampersand in the comment field is replaced with the login name (capitalized) by some utilities. For example, we could have</p><pre>
    sar:x:205:105:Steve Rago, SF 5-121, 555-1111, 555-2222:/home/sar:/bin/sh
</pre><br>
<p class="docList">Then we could use <tt>finger</tt> to print information about Steve Rago.</p><pre>
    $ <span class="docEmphStrong">finger -p sar</span>
    Login: sar                      Name: Steve Rago
    Directory: /home/sar            Shell: /bin/sh
    Office:  SF 5-121,  555-1111    Home Phone:  555-2222
    On since Mon Jan 19 03:57 (EST) on ttyv0 (messages off)
    No Mail.
</pre><br>
<p class="docList">Even if your system doesn't support the <tt>finger</tt> command, these fields can still go into the comment field, since that field is simply a comment and not interpreted by system utilities.</P></li></UL>
<p class="docText">Some systems provide the <tt>vipw</tt> command to allow administrators to edit the password file. The <tt>vipw</tt> command serializes changes to the password file and makes sure that any additional files are consistent with the changes made. It is also common for systems to provide similar functionality through graphical user interfaces.</p>
<p class="docText">POSIX.1 defines only two functions to fetch entries from the password file. These functions allow us to look up an entry given a user's login name or numerical user ID.</P>
<a name="inta125"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="none" cellpadding="5"><colgroup><col width="500"></colgroup><thead></thead><tr><td class="docTableCell" align="left" valign="top"><p class="docText">
<pre>
#include &lt;pwd.h&gt;

struct passwd *getpwuid(uid_t <span class="docEmphItalicAlt">uid</span>);

struct passwd *getpwnam(const char *<span class="docEmphItalicAlt">name</span>);
</pre><br>

</p></td></tr><tr><td class="docTableCell" align="right" valign="top"><p class="docText">Both return: pointer if OK, <tt>NULL</tt> on error</p></td></tr></table></p><br>
<p class="docText">The <tt>getpwuid</tt> function is used by the <tt>ls</tt>(1) program to map the numerical user ID contained in an i-node into a user's login name. The <tt>getpwnam</tt> function is used by the <tt>login</tt>(1) program when we enter our login name.</p>
<p class="docText"><a name="idd1e42406"></a><a name="idd1e42411"></a><a name="idd1e42418"></a><a name="idd1e42423"></a><a name="idd1e42428"></a><a name="idd1e42435"></a><a name="idd1e42440"></a><a name="idd1e42449"></a><a name="idd1e42456"></a><a name="idd1e42459"></a>Both functions return a pointer to a <tt>passwd</tt> structure that the functions fill in. This structure is usually a <tt>static</tt> variable within the function, so its contents are overwritten each time we call either of these functions.</p>
<p class="docText">These two POSIX.1 functions are fine if we want to look up either a login name or a user ID, but some programs need to go through the entire password file. The following three functions can be used for this.</p>
<a name="inta34"></a><P><table cellspacing="0" class="allBorders" border="1" RULES="none" cellpadding="5"><colgroup><col width="500"></colgroup><thead></thead><TR><td class="docTableCell" align="left" valign="top"><p class="docText">
<pre>
#include &lt;pwd.h&gt;

struct passwd *getpwent(void);
</pre><BR>

</P></TD></tr><TR><TD class="docTableCell" align="right" valign="top"><p class="docText">Returns: pointer if OK, <tt>NULL</tt> on error or end of file</P></td></TR><tr><TD class="docTableCell" align="left" valign="top"><p class="docText">
<pre>
void setpwent(void);

void endpwent(void);
</pre><BR>

</P></td></TR></table></P><br>
<blockquote>
<p class="docText">These three functions are not part of the base POSIX.1 standard. They are defined as XSI extensions in the Single UNIX Specification. As such, all UNIX systems are expected to provide them.</P>
</blockquote>
<p class="docText">We call <tt>getpwent</tt> to return the next entry in the password file. As with the two POSIX.1 functions, <tt>getpwent</tt> returns a pointer to a structure that it has filled in. This structure is normally overwritten each time we call this function. If this is the first call to this function, it opens whatever files it uses. There is no order implied when we use this function; the entries can be in any order, because some systems use a hashed version of the file <tt>/etc/passwd</tt>.</P>
<p class="docText">The function <tt>setpwent</tt> rewinds whatever files it uses, and <tt>endpwent</tt> closes these files. When using <tt>getpwent</tt>, we must always be sure to close these files by calling <tt>endpwent</tt> when we're through. Although <tt>getpwent</tt> is smart enough to know when it has to open its files (the first time we call it), it never knows when we're through.</p>
<a name="ch06ex01"></a>
<h5 class="docExampleTitle">Example</h5>
<p class="docText"><a class="docLink" href="#ch06fig02">Figure 6.2</a> shows an implementation of the function <tt>getpwnam</tt>.</p>
<p class="docText"><a name="idd1e42564"></a><a name="idd1e42567"></a><a name="idd1e42570"></a><a name="idd1e42575"></a><a name="idd1e42578"></a><a name="idd1e42581"></a><a name="idd1e42584"></a>The call to <tt>setpwent</tt> at the beginning is self-defense: we ensure that the files are rewound, in case the caller has already opened them by calling <tt>getpwent</tt>. The call to <tt>endpwent</tt> when we're done is because neither <tt>getpwnam</tt> nor <tt>getpwuid</tt> should leave any of the files open.</P>

<a name="ch06fig02"></a>
<h5 class="docExampleTitle">Figure 6.2. The <tt>getpwnam</tt> function</H5>

<pre>
#include &lt;pwd.h&gt;
#include &lt;stddef.h&gt;
#include &lt;string.h&gt;

struct passwd *
getpwnam(const char *name)
{
    struct passwd  *ptr;

    setpwent();
    while ((ptr = getpwent()) != NULL)
        if (strcmp(name, ptr-&gt;pw_name) == 0)
            break;      /* found a match */
    endpwent();
    return(ptr);    /*a ptr is NULL if no match found */
}
</pre><br>



<UL></ul></td></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch06lev1sec1.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch06lev1sec3.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--208-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--208-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
